package com.evil.kingdom.pojo.enums.socket;

import com.evil.common.core.exception.BusinessException;
import com.evil.kingdom.pojo.dto.alive.*;
import com.evil.kingdom.pojo.entity.config.value.Almanac;
import com.evil.kingdom.pojo.enums.result.RCodeEnum;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.Optional;

/**
 * socket消息类型
 *
 * @author liyang
 * @date 2024-06-01 13:19
 */
@Getter
@AllArgsConstructor
public enum MessageTypeEnum {

    SUCCESS(0, "连接成功", AliveSuccess.class),
    WARFARE(1, "出征", AliveWarfare.class),
    WARFARE_ACCESS(2, "出征到达", AliveWarfareAccess.class),
    WARFARE_MEET(3, "出征相遇", AliveWarfareMeet.class),
    WARFARE_ATTACK(4, "出征相遇", AliveWarfareAttack.class),
    WARFARE_OUTCOME(5, "出征结果", AliveWarfareOutcome.class),

    ALMANAC(10, "世界时间", Almanac.class),
    ;

    @JsonValue
    private final int type;
    private final String name;
    private final Class<? extends AliveMessageData> messageClass;

    MessageTypeEnum(Integer type) {
        MessageTypeEnum typeEnum = MessageTypeEnum.findByType(type);
        this.type = type;
        this.name = typeEnum.name;
        this.messageClass = typeEnum.messageClass;
    }

    public static Optional<MessageTypeEnum> isExistByType(Integer type) {
        if (null == type) {
            return Optional.empty();
        }
        return Arrays.stream(values()).filter(e -> e.type == type).findFirst();
    }

    public static MessageTypeEnum findByType(Integer type) {
        return MessageTypeEnum.isExistByType(type).orElseThrow(MessageTypeEnum::error);
    }

    public static <T extends AliveMessageData> Optional<MessageTypeEnum> isExistByMessageClass(Class<T> messageClass) {
        if (null == messageClass) {
            return Optional.empty();
        }
        return Arrays.stream(values()).filter(e -> e.messageClass.equals(messageClass)).findFirst();
    }

    public static <T extends AliveMessageData> MessageTypeEnum findByMessageClass(Class<T> messageClass) {
        return MessageTypeEnum.isExistByMessageClass(messageClass).orElseThrow(MessageTypeEnum::error);
    }

    public static BusinessException error() {
        return new BusinessException(RCodeEnum.ERROR_PARAMETER, "socket消息类型错误");
    }
}
